

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" href="/img/favicon.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="Blue~u~u~u">
  <meta name="author" content="Blue~u~u~u">
  <meta name="keywords" content="">
  <meta name="description" content="Spring Security简介Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证和授权的过程。官网：https:&#x2F;&#x2F;spring.io&#x2F;projects&#x2F;spring-security 中文官网：https:&#x2F;&#x2F;www.w3cschool.cn&#x2F;springsecurity&#x2F; ​    对应的maven坐标： 12">
<meta property="og:type" content="article">
<meta property="og:title" content="SpringSecurity">
<meta property="og:url" content="http://www.slx.blue/2022/01/08/SpringSecurity/index.html">
<meta property="og:site_name" content="Blue~u~u~u~u">
<meta property="og:description" content="Spring Security简介Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证和授权的过程。官网：https:&#x2F;&#x2F;spring.io&#x2F;projects&#x2F;spring-security 中文官网：https:&#x2F;&#x2F;www.w3cschool.cn&#x2F;springsecurity&#x2F; ​    对应的maven坐标： 12">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s002.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s003.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s004.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s005.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s006.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s007.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s008.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s009.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s010.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s011.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s012.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s013.png">
<meta property="og:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s014.png">
<meta property="article:published_time" content="2022-01-08T13:17:07.000Z">
<meta property="article:modified_time" content="2022-01-08T13:18:38.117Z">
<meta property="article:author" content="Blue~u~u~u">
<meta property="article:tag" content="SpringSecurity">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://www.slx.blue/2022/01/08/SpringSecurity/s002.png">
  
  <title>SpringSecurity - Blue~u~u~u~u</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css" />
  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"www.slx.blue","root":"/","version":"1.8.12","typing":{"enable":true,"typeSpeed":180,"cursorChar":"_","loop":true},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname"}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>

<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css"/>
<script src="/live2d-widget/autoload.js"></script>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>Blue~u~u</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/links/">
                <i class="iconfont icon-link-fill"></i>
                友链
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/images/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="SpringSecurity">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2022-01-08 21:17" pubdate>
        2022年1月8日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      27k 字
    </span>
  

  
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      84 分钟
    </span>
  

  
  
    
      <!-- 不蒜子统计文章PV -->
      <span id="busuanzi_container_page_pv" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="busuanzi_value_page_pv"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">SpringSecurity</h1>
            
              <p class="note note-info">
                
                  本文最后更新于：5 个月前
                
              </p>
            
            <div class="markdown-body">
              <h2 id="Spring-Security简介"><a href="#Spring-Security简介" class="headerlink" title="Spring Security简介"></a><strong>Spring Security简介</strong></h2><p>Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证和授权的过程。官网：<a target="_blank" rel="noopener" href="https://spring.io/projects/spring-security">https://spring.io/projects/spring-security</a></p>
<p>中文官网：<a target="_blank" rel="noopener" href="https://www.w3cschool.cn/springsecurity/">https://www.w3cschool.cn/springsecurity/</a></p>
<p>​    对应的maven坐标：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.security<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-security-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.security<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-security-config<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>常用的权限框架除了Spring Security，还有Apache的shiro框架。</p>
<h3 id="【小结】"><a href="#【小结】" class="headerlink" title="【小结】"></a><a href="#%E5%B0%8F%E7%BB%93-">【小结】</a></h3><ol>
<li>SpringSecurity是Spring家族的一个安全框架, 简化我们开发里面的认证和授权过程</li>
<li>SpringSecurity内部封装了Filter（只需要在web.xml容器中配置一个过滤器–代理过滤器，真实的过滤器在spring的容器中配置）</li>
<li>常见的安全框架</li>
</ol>
<ul>
<li>Spring的 <code>SpringSecurity</code></li>
<li>Apache的Shiro <code>http://shiro.apache.org/</code></li>
</ul>
<h2 id="Spring-Security入门案例"><a href="#Spring-Security入门案例" class="headerlink" title="Spring Security入门案例"></a><strong>Spring Security入门案例</strong></h2><p>【需求】</p>
<p> 使用Spring Security进行控制: 网站(一些页面)需要登录才能访问（认证）</p>
<ol>
<li>创建Maven工程 <code>spring_security_demo</code>,导入坐标</li>
<li>配置 <code>web.xml</code> (前端控制器, <code>SpringSecurity</code>相关的过滤器)</li>
<li>创建 <code>spring-security.xml</code>（核心）</li>
</ol>
<h3 id="入门案例"><a href="#入门案例" class="headerlink" title="入门案例"></a>入门案例</h3><ol>
<li><p>创建maven工程，打包方式为war。</p>
<p>pom.xml</p>
</li>
</ol>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>war<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">spring.version</span>&gt;</span>5.0.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">spring.version</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="hljs-tag">&lt;/<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.source</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.source</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.target</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.target</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-core<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-webmvc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-context-support<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-test<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-jdbc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$&#123;spring.version&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.security<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-security-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.security<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-security-config<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>javax.servlet<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>servlet-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>provided<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.tomcat.maven<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>tomcat7-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span><br>                    <span class="hljs-comment">&lt;!-- 指定端口 --&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">port</span>&gt;</span>85<span class="hljs-tag">&lt;/<span class="hljs-name">port</span>&gt;</span><br>                    <span class="hljs-comment">&lt;!-- 请求路径 --&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">path</span>&gt;</span>/<span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>内置提供 <code>index.html</code> 页面，内容为“登录成功”!!</p>
<ol start="2">
<li><p>配置web.xml</p>
<p>1：DelegatingFilterProxy用于整合第三方框架（代理过滤器，非真正的过滤器，真正的过滤器需要在spring的配置文件）==</p>
<p>2：springmvc的核心控制器</p>
<p>在<code>web.xml</code> 中主要配置 <code>SpringMVC</code> 的 <code>DispatcherServlet</code> 和用于整合第三方框架的<code>DelegatingFilterProxy</code>（代理过滤器，真正的过滤器在spring的配置文件），用于整合<code>Spring Security</code>。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">web-app</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span><br><span class="hljs-tag">         <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://java.sun.com/xml/ns/javaee&quot;</span></span><br><span class="hljs-tag">         <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;</span></span><br><span class="hljs-tag">         <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;WebApp_ID&quot;</span> <span class="hljs-attr">version</span>=<span class="hljs-string">&quot;3.0&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">filter</span>&gt;</span><br>        <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">         1：DelegatingFilterProxy用于整合第三方框架（代理过滤器，非真正的过滤器，真正的过滤器需要在spring的配置文件）</span><br><span class="hljs-comment">          整合Spring Security时过滤器的名称必须为springSecurityFilterChain，</span><br><span class="hljs-comment">          否则会抛出NoSuchBeanDefinitionException异常</span><br><span class="hljs-comment">        --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>springSecurityFilterChain<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">filter-class</span>&gt;</span>org.springframework.web.filter.DelegatingFilterProxy<span class="hljs-tag">&lt;/<span class="hljs-name">filter-class</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">filter</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">filter-mapping</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>springSecurityFilterChain<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>/*<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">filter-mapping</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 2：springmvc的核心控制器--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">servlet</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>springmvc<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-class</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 指定加载的配置文件 ，通过参数contextConfigLocation加载 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">init-param</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">param-name</span>&gt;</span>contextConfigLocation<span class="hljs-tag">&lt;/<span class="hljs-name">param-name</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">param-value</span>&gt;</span>classpath:spring-security.xml<span class="hljs-tag">&lt;/<span class="hljs-name">param-value</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">init-param</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">load-on-startup</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">load-on-startup</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">servlet</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-mapping</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>springmvc<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>*.do<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">servlet-mapping</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">web-app</span>&gt;</span><br></code></pre></td></tr></table></figure></li>
<li><p>配置spring-security.xml</p>
<p>1：定义哪些链接可以放行</p>
<p>2：定义哪些链接不可以放行，即需要有角色、权限才可以放行</p>
<p>3：认证管理，定义登录账号名和密码，并授予访问的角色、权限</p>
<p>在 <code>spring-security.xml</code> 中主要配置 <code>Spring Security</code> 的拦截规则和认证管理器。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:dubbo</span>=<span class="hljs-string">&quot;http://code.alibabatech.com/schema/dubbo&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:mvc</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/mvc&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:security</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/security&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/beans/spring-beans.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/mvc</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/mvc/spring-mvc.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://code.alibabatech.com/schema/dubbo</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://code.alibabatech.com/schema/dubbo/dubbo.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/context</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/context/spring-context.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                          http://www.springframework.org/schema/security</span></span><br><span class="hljs-string"><span class="hljs-tag">                          http://www.springframework.org/schema/security/spring-security.xsd&quot;</span>&gt;</span><br><br>     <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">       ① 配置哪些链接可以放行(没有认证通过也可以访问的资源)</span><br><span class="hljs-comment">       security=&quot;none&quot;：没有权限</span><br><span class="hljs-comment">       pattern=&quot;/login.html&quot;：没有任何权限，可以访问login.html</span><br><span class="hljs-comment">     --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;security:http security=&quot;none&quot; pattern=&quot;/login.html&quot;&gt;&lt;/security:http&gt;--&gt;</span><br><br>    <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">    ② 定义哪些链接不可以放行(必须通过认证才能访问的资源)，及需要有角色，有权限才可以放行访问资源</span><br><span class="hljs-comment">    &lt;security:http auto-config=&quot;true&quot; use-expressions=&quot;true&quot;&gt;</span><br><span class="hljs-comment">          auto-config=&quot;true&quot;:开启自动配置 由springsecurity提供登录页面，提供登录的url地址，退出的url地址</span><br><span class="hljs-comment">          use-expressions=&quot;true&quot;：使用表达式的方式控制权限</span><br><span class="hljs-comment">             security:intercept-url：定义哪些链接不可以放行，需要当前角色和权限才能放行</span><br><span class="hljs-comment">                pattern=&quot;/**&quot;：要求系统中的所有资源，都必须通过角色和权限才能访问</span><br><span class="hljs-comment">                access：指定角色和权限</span><br><span class="hljs-comment">                   如果使用表达式use-expressions=&quot;true&quot;</span><br><span class="hljs-comment">                       access=&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)：表示具有ROLE_ADMIN的角色才能访问系统的资源</span><br><span class="hljs-comment">                   如果不使用表达式use-expressions=&quot;false&quot;</span><br><span class="hljs-comment">                       access=&quot;ROLE_ADMIN：表示具有ROLE_ADMIN的角色才能访问系统的资源</span><br><span class="hljs-comment">    --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">auto-config</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">use-expressions</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/**&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">      ③ 认证管理：定义登录账号和密码，并授予当前用户访问的角色或权限</span><br><span class="hljs-comment">        （1）：将用户名和密码：当前用户具有的角色，写死到配置文件中（现在:入门）</span><br><span class="hljs-comment">                security:user name=&quot;admin&quot; :登录名</span><br><span class="hljs-comment">                authorities=&quot;ROLE_ADMIN&quot;   ：角色(ROLE_ADMIN),权限</span><br><span class="hljs-comment">                password=&quot;admin&quot;          ：密码</span><br><span class="hljs-comment">         （2）：用户名和密码，当前用户具有的角色，从数据库中查询（后续）</span><br><span class="hljs-comment">    --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-manager</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-provider</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">security:user-service</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">security:user</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;admin&quot;</span> <span class="hljs-attr">authorities</span>=<span class="hljs-string">&quot;ROLE_ADMIN&quot;</span> <span class="hljs-attr">password</span>=<span class="hljs-string">&quot;admin&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:user</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">security:user-service</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-provider</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-manager</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>请求 url 地址：<code>http://localhost:85/</code></p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s002.png" srcset="/img/loading.gif" lazyload alt="s002"></p>
<p>输入错误用户名和密码    </p>
<p>​                                                    <img src="http://www.slx.blue/2022/01/08/SpringSecurity/s003.png" srcset="/img/loading.gif" lazyload alt="s003"></p>
</li>
</ol>
<p>输入正确用户名和密码（admin/admin），因为 spring security 提供了一套安全机制，登录的时候进行了拦截，参考系统源码<code>PasswordEncoderFactories</code></p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s004.png" srcset="/img/loading.gif" lazyload alt="s004"></p>
<p>需要修改配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:user</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;admin&quot;</span> <span class="hljs-attr">authorities</span>=<span class="hljs-string">&quot;ROLE_ADMIN&quot;</span> <span class="hljs-attr">password</span>=<span class="hljs-string">&quot;&#123;noop&#125;admin&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:user</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>输入正确用户名和密码（admin/admin），缺少资源</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s005.png" srcset="/img/loading.gif" lazyload alt="s005"></p>
<p>此时说明没有登录成功的页面。</p>
<p>{noop}：表示当前使用的密码为明文。表示当前密码不需要加密 <code>PasswordEncoderFactories</code></p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s006.png" srcset="/img/loading.gif" lazyload alt="s006"></p>
<p>在 <code>webapp</code> 文件夹下面，新建 <code>index.html</code> ，可以正常访问 <code>index.html</code></p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s007.png" srcset="/img/loading.gif" lazyload alt="s007"></p>
<h3 id="【小结】-1"><a href="#【小结】-1" class="headerlink" title="【小结】"></a><a href="#%E5%B0%8F%E7%BB%93-">【小结】</a></h3><p>使用步骤</p>
<ol>
<li>创建Maven工程, 添加坐标</li>
<li>配置web.xml(前端控制器,==springSecurity权限相关的过滤器==)</li>
<li>创建spring-security.xml(自动配置,使用表达式的方式完成授权，只要具有ROLE_ADMIN的角色权限才能访问系统中的所有功能； 授权管理器，指定用户名admin，密码admin，具有ROLE_ADMIN的角色权限)</li>
</ol>
<p>注意实现</p>
<p> 1.在web.xml里面配置的权限相关的过滤器名字==不能改==（springSecurityFilterChain）</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">filter</span>&gt;</span>   <br>   <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>springSecurityFilterChain<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">filter-class</span>&gt;</span>org.springframework.web.filter.DelegatingFilterProxy<span class="hljs-tag">&lt;/<span class="hljs-name">filter-class</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">filter</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">filter-mapping</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>springSecurityFilterChain<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>/*<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">filter-mapping</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p> 2.入门案例里面没有指定密码加密方式的. 配置密码的时候的加=={noop}==</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:user-service</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">security:user</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;admin&quot;</span> <span class="hljs-attr">password</span>=<span class="hljs-string">&quot;&#123;noop&#125;admin&quot;</span> <span class="hljs-attr">authorities</span>=<span class="hljs-string">&quot;ROLE_ADMIN&quot;</span>/&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">security:user-service</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h2 id="Spring-Security进阶"><a href="#Spring-Security进阶" class="headerlink" title="Spring Security进阶"></a><strong>Spring Security进阶</strong></h2><p>前面我们已经完成了Spring Security的入门案例，通过入门案例我们可以看到，Spring Security将我们项目中的所有资源都保护了起来，要访问这些资源必须要完成认证而且需要具有ROLE_ADMIN角色。</p>
<p>但是入门案例中的使用方法离我们真实生产环境还差很远，还存在如下一些问题：</p>
<p>1、项目中我们将所有的资源（所有请求URL）都保护起来，实际环境下往往有一些资源不需要认证也可以访问，也就是可以匿名访问。</p>
<p>2、登录页面是由框架生成的，而我们的项目往往会使用自己的登录页面。</p>
<p>3、直接将用户名和密码配置在了配置文件中，而真实生产环境下的用户名和密码往往保存在数据库中。</p>
<p>4、在配置文件中配置的密码使用明文，这非常不安全，而真实生产环境下密码需要进行加密。</p>
<p>需要对这些问题进行改进。</p>
<ol>
<li>配置可匿名访问的资源(不需要登录,权限 角色 就可以访问的资源)</li>
<li>使用指定的登录页面（login.html)</li>
<li>从数据库查询用户信息</li>
<li>对密码进行加密</li>
<li>配置多种校验规则（对访问的页面做权限控制）</li>
<li>注解方式权限控制（对访问的Controller类做权限控制）</li>
<li>退出登录</li>
</ol>
<h3 id="配置可匿名访问的资源"><a href="#配置可匿名访问的资源" class="headerlink" title="配置可匿名访问的资源"></a><strong>配置可匿名访问的资源</strong></h3><p>1：在项目中创建js、css目录并在两个目录下提供任意一些测试文件</p>
<p>2：在spring-security.xml文件中配置，指定哪些资源可以匿名访问</p>
<p>第一步：在项目中创建js、css目录并在两个目录下提供任意一些测试文件</p>
<p>把 meinian_web 项目里面的 js 和 css 文件夹 拷贝到项目中</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s008.png" srcset="/img/loading.gif" lazyload alt="s008"></p>
<p>访问<a target="_blank" rel="noopener" href="http://localhost:85/js/vue.js">http://localhost:85/js/vue.js</a></p>
<p>请求 vue.js 文件 ，发现被拦截不能访问</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s009.png" srcset="/img/loading.gif" lazyload alt="s009"></p>
<p>第二步：在spring-security.xml文件中配置，指定哪些资源可以匿名访问</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">  http：用于定义相关权限控制</span><br><span class="hljs-comment">  指定哪些资源不需要进行权限校验，可以使用通配符</span><br><span class="hljs-comment">--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/js/**&quot;</span> /&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/css/**&quot;</span> /&gt;</span><br></code></pre></td></tr></table></figure>

<p>通过上面的配置可以发现，js和css目录下的文件可以在没有认证的情况下任意访问。</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s010.png" srcset="/img/loading.gif" lazyload alt="s010"></p>
<h3 id="使用指定的登录页面"><a href="#使用指定的登录页面" class="headerlink" title="使用指定的登录页面"></a><strong>使用指定的登录页面</strong></h3><ol>
<li>在webapp文件夹下面，提供login.html作为项目的登录页面</li>
<li>修改spring-security.xml文件，指定login.html页面可以匿名访问</li>
<li>修改spring-security.xml文件，加入表单登录信息的配置</li>
<li>修改spring-security.xml文件，关闭csrfFilter过滤器</li>
</ol>
<p>第一步：提供login.html作为项目的登录页面</p>
<p>1：用户名是username</p>
<p>2：密码是password</p>
<p>3：登录的url是login.do</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>登录<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">&quot;/login.do&quot;</span> <span class="hljs-attr">method</span>=<span class="hljs-string">&quot;post&quot;</span>&gt;</span><br>    username:<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;username&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    password:<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;password&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;password&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;submit&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;submit&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>第二步：修改spring-security.xml文件，指定login.html页面可以匿名访问，否则无法访问。</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">&lt;<span class="hljs-keyword">security</span>:http <span class="hljs-keyword">security</span>=&quot;none&quot; pattern=&quot;/login.html&quot; /&gt;<br></code></pre></td></tr></table></figure>

<p>第三步：修改spring-security.xml文件，加入表单登录信息的配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:dubbo</span>=<span class="hljs-string">&quot;http://code.alibabatech.com/schema/dubbo&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:mvc</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/mvc&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xmlns:security</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/security&quot;</span></span><br><span class="hljs-tag">       <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/beans/spring-beans.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/mvc</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/mvc/spring-mvc.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://code.alibabatech.com/schema/dubbo</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://code.alibabatech.com/schema/dubbo/dubbo.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/context</span></span><br><span class="hljs-string"><span class="hljs-tag">                  http://www.springframework.org/schema/context/spring-context.xsd</span></span><br><span class="hljs-string"><span class="hljs-tag">                          http://www.springframework.org/schema/security</span></span><br><span class="hljs-string"><span class="hljs-tag">                          http://www.springframework.org/schema/security/spring-security.xsd&quot;</span>&gt;</span><br>     <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">      ① 配置哪些链接可以放行(没有认证通过也可以访问的资源)</span><br><span class="hljs-comment">      security=&quot;none&quot;：没有权限</span><br><span class="hljs-comment">      pattern=&quot;/login.html&quot;：没有任何权限，可以访问login.html</span><br><span class="hljs-comment">    --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;security:http security=&quot;none&quot; pattern=&quot;/login.html&quot;&gt;&lt;/security:http&gt;--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/login.html&quot;</span> /&gt;</span><br>    <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">  http：用于定义相关权限控制</span><br><span class="hljs-comment">  指定哪些资源不需要进行权限校验，可以使用通配符</span><br><span class="hljs-comment">--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/js/**&quot;</span> /&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/css/**&quot;</span> /&gt;</span><br><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">  form-login：定义表单登录信息</span><br><span class="hljs-comment">            login-page=&quot;/login.html&quot;：表示指定登录页面</span><br><span class="hljs-comment">            username-parameter=&quot;username&quot;：使用登录名的名称，默认值是username</span><br><span class="hljs-comment">            password-parameter=&quot;password&quot;：使用登录名的密码，默认值是password</span><br><span class="hljs-comment">            login-processing-url=&quot;/login.do&quot;：表示登录的url地址</span><br><span class="hljs-comment">            default-target-url=&quot;/index.html&quot;：登录成功后的url地址</span><br><span class="hljs-comment">            authentication-failure-url=&quot;/login.html&quot;：认证失败后跳转的url地址，失败后指定/login.html</span><br><span class="hljs-comment">            always-use-default-target=&quot;true&quot;：登录成功后，始终跳转到default-target-url指定的地址，即登录成功的默认地址</span><br><span class="hljs-comment">--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">auto-config</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">use-expressions</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/**&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:form-login</span> <span class="hljs-attr">login-page</span>=<span class="hljs-string">&quot;/login.html&quot;</span></span><br><span class="hljs-tag">                             <span class="hljs-attr">username-parameter</span>=<span class="hljs-string">&quot;username&quot;</span></span><br><span class="hljs-tag">                             <span class="hljs-attr">password-parameter</span>=<span class="hljs-string">&quot;password&quot;</span></span><br><span class="hljs-tag">                             <span class="hljs-attr">login-processing-url</span>=<span class="hljs-string">&quot;/login.do&quot;</span></span><br><span class="hljs-tag">                             <span class="hljs-attr">default-target-url</span>=<span class="hljs-string">&quot;/index.html&quot;</span></span><br><span class="hljs-tag">                             <span class="hljs-attr">authentication-failure-url</span>=<span class="hljs-string">&quot;/login.html&quot;</span></span><br><span class="hljs-tag">                              <span class="hljs-attr">always-use-default-target</span>=<span class="hljs-string">&quot;true&quot;</span></span><br><span class="hljs-tag">        /&gt;</span><br>        <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">  csrf：对应CsrfFilter过滤器</span><br><span class="hljs-comment">  disabled：是否启用CsrfFilter过滤器，如果使用自定义登录页面需要关闭此项，否则登录操作会被禁用（403）</span><br><span class="hljs-comment">--&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">security:csrf</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:csrf</span>&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h4 id="注意1："><a href="#注意1：" class="headerlink" title="注意1："></a><strong>注意1：</strong></h4><p>如果用户名和密码输入正确。抛出异常：<img src="http://www.slx.blue/2022/01/08/SpringSecurity/s011.png" srcset="/img/loading.gif" lazyload alt="s011"></p>
<p>分析原因：</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s012.png" srcset="/img/loading.gif" lazyload alt="s012"></p>
<p>Spring-security采用盗链机制，其中_csrf使用token标识和随机字符，每次访问页面都会随机生成，然后和服务器进行比较，成功可以访问，不成功不能访问。</p>
<p>解决方案：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--关闭盗链安全请求--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:csrf</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">&quot;true&quot;</span> /&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s013.png" srcset="/img/loading.gif" lazyload alt="s013"></p>
<h3 id="从数据库查询用户信息"><a href="#从数据库查询用户信息" class="headerlink" title="从数据库查询用户信息"></a><strong>从数据库查询用户信息</strong></h3><ol>
<li>定义UserService类，实现UserDetailsService接口。</li>
<li>修改spring-security.xml配置（注入UserService）</li>
</ol>
<p>如果我们要从数据库动态查询用户信息，就必须按照spring security框架的要求提供一个实现UserDetailsService接口的实现类，并按照框架的要求进行配置即可。框架会自动调用实现类中的方法并自动进行密码校验。</p>
<p>第一步：创建java bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>&#123;<br>    <span class="hljs-keyword">private</span> String username;<br>    <span class="hljs-keyword">private</span> String password;<br>    <span class="hljs-keyword">private</span> String telephone;<br>    <span class="hljs-comment">// 生成set get 和 tostring 方法</span><br>&#125;<br></code></pre></td></tr></table></figure>

<p>第二步：定义UserService类，实现UserDetailsService接口。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Component</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">UserDetailsService</span> </span>&#123;<br>    <span class="hljs-comment">//模拟数据库中的用户数据</span><br>   <span class="hljs-keyword">static</span> Map&lt;String,com.atguigu.pojo.User&gt; map =   <span class="hljs-keyword">new</span> HashMap&lt;String,com.atguigu.pojo.User&gt;();<br><br>   <span class="hljs-keyword">static</span> &#123;<br>       com.atguigu.pojo.User user1 =  <span class="hljs-keyword">new</span> com.atguigu.pojo.User();<br>       user1.setUsername(<span class="hljs-string">&quot;admin&quot;</span>);<br>       user1.setPassword(<span class="hljs-string">&quot;admin&quot;</span>);<br>       user1.setTelephone(<span class="hljs-string">&quot;123&quot;</span>);<br><br>       com.atguigu.pojo.User user2 =  <span class="hljs-keyword">new</span> com.atguigu.pojo.User();<br>       user2.setUsername(<span class="hljs-string">&quot;zhangsan&quot;</span>);<br>       user2.setPassword(<span class="hljs-string">&quot;123&quot;</span>);<br>       user2.setTelephone(<span class="hljs-string">&quot;321&quot;</span>);<br><br>       map.put(user1.getUsername(),user1);<br>       map.put(user2.getUsername(),user2);<br>   &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 根据用户名加载用户信息</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> username</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     * <span class="hljs-doctag">@throws</span> UsernameNotFoundException</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> UserDetails <span class="hljs-title">loadUserByUsername</span><span class="hljs-params">(String username)</span> <span class="hljs-keyword">throws</span> UsernameNotFoundException </span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;username&quot;</span>+username);<br>        <span class="hljs-comment">//模拟根据用户名查询数据库</span><br>        com.atguigu.pojo.User userInDb = map.get(username);<br><br>        <span class="hljs-keyword">if</span> (userInDb==<span class="hljs-keyword">null</span>)&#123;<br>            <span class="hljs-comment">//根据用户名没有查询到用户，抛出异常，表示登录名输入有误</span><br>            <span class="hljs-keyword">return</span>  <span class="hljs-keyword">null</span>;<br>        &#125;<br>        <span class="hljs-comment">//模拟数据库中的密码，后期需要查询数据库</span><br>        String passwordInDb =<span class="hljs-string">&quot;&#123;noop&#125;&quot;</span> + userInDb.getPassword();<br>        <span class="hljs-comment">//授权，后期需要改为查询数据库动态获得用户拥有的权限和角色</span><br>        List&lt;GrantedAuthority&gt; lists = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;add&quot;</span>));<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;delete&quot;</span>));<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;ROLE_ADMIN&quot;</span>));<br><br><span class="hljs-comment">//public User(String username, String password,</span><br><span class="hljs-comment">//                Collection&lt;? extends GrantedAuthority &gt; authorities)</span><br>        <span class="hljs-comment">//返回User，参数一：存放登录名，</span><br>        <span class="hljs-comment">// 参数二：存放数据库查询的密码（数据库获取的密码，默认会和页面获取的密码进行比对，成功跳转到成功页面，失败回到登录页面，并抛出异常表示失败），存放当前用户具有的角色</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> User(username,passwordInDb,lists);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>第三步：spring-security.xml：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">    三：认证管理，定义登录账号名和密码，并授予访问的角色、权限</span><br><span class="hljs-comment">    authentication-manager：认证管理器，用于处理认证操作</span><br><span class="hljs-comment">--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-manager</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">        authentication-provider：认证提供者，执行具体的认证逻辑</span><br><span class="hljs-comment">    --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-provider</span> <span class="hljs-attr">user-service-ref</span>=<span class="hljs-string">&quot;userService&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-provider</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-manager</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">context:component-scan</span> <span class="hljs-attr">base-package</span>=<span class="hljs-string">&quot;com&quot;</span>/&gt;</span><br></code></pre></td></tr></table></figure>

<p>本章节我们提供了UserService实现类，并且按照框架的要求实现了UserDetailsService接口。在spring配置文件中注册UserService，指定其作为认证过程中根据用户名查询用户信息的处理类。当我们进行登录操作时，spring security框架会调用UserService的loadUserByUsername方法查询用户信息，并根据此方法中提供的密码和用户页面输入的密码进行比对来实现认证操作。</p>
<h3 id="对密码进行加密"><a href="#对密码进行加密" class="headerlink" title="对密码进行加密"></a><strong>对密码进行加密</strong></h3><p>前面我们使用的密码都是明文的，这是非常不安全的。一般情况下用户的密码需要进行加密后再保存到数据库中。</p>
<p>常见的密码加密方式有：</p>
<p>3DES、AES、DES：使用对称加密算法，可以通过解密来还原出原始密码</p>
<p>MD5、SHA1：使用单向HASH算法，无法通过计算还原出原始密码，但是可以建立彩虹表进行查表破解</p>
<p>MD5可进行<strong>加盐</strong>加密，保证安全</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestMD5</span> </span>&#123;<br><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testMD5</span><span class="hljs-params">()</span></span>&#123;<br>        <span class="hljs-comment">// 密码同样是1234却变成了密码不相同</span><br>        System.out.println(MD5Utils.md5(<span class="hljs-string">&quot;1234xiaowang&quot;</span>)); <span class="hljs-comment">//a8231077b3d5b40ffadee7f4c8f66cb7</span><br>        System.out.println(MD5Utils.md5(<span class="hljs-string">&quot;1234xiaoli&quot;</span>)); <span class="hljs-comment">//7d5250d8620fcdb53b25f96a1c7be591</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>同样的密码值，盐值不同，加密的结果不同。</p>
<p>bcrypt：将salt随机并混入最终加密后的密码，验证时也无需单独提供之前的salt，从而无需单独处理salt问题</p>
<p><strong>spring security中的BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密。</strong>SHA系列是Hash算法，不是加密算法，使用加密算法意味着可以解密（这个与编码/解码一样），但是采用Hash处理，其过程是不可逆的。</p>
<p>**（1）加密(encode)**：注册用户时，使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理，得到密码的hash值，然后将其存入数据库中。</p>
<p>**（2）密码匹配(matches)**：用户登录时，密码匹配阶段并没有进行密码解密（因为密码经过Hash处理，是不可逆的），而是使用相同的算法把用户输入的密码进行hash处理，得到密码的hash值，然后将其与从数据库中查询到的密码hash值进行比较。如果两者相同，说明用户输入的密码正确。</p>
<p>这正是为什么处理密码时要用hash算法，而不用加密算法。因为这样处理即使数据库泄漏，黑客也很难破解密码。</p>
<p>在 <code>meinian_common</code>项目的 <code>test</code> 文件夹下面新建测试代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> org.junit.Test;<br><span class="hljs-keyword">import</span> org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;<br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestSpringSecurity</span> </span>&#123;<br>    <span class="hljs-comment">// SpringSecurity加盐加密</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testSpringSecurity</span><span class="hljs-params">()</span></span>&#123;<br>        <span class="hljs-comment">// $2a$10$dyIf5fOjCRZs/pYXiBYy8uOiTa1z7I.mpqWlK5B/0icpAKijKCgxe</span><br>        <span class="hljs-comment">// $2a$10$OphM.agzJ55McriN2BzCFeoLZh/z8uL.8dcGx.VCnjLq01vav7qEm</span><br><br>        BCryptPasswordEncoder encoder = <span class="hljs-keyword">new</span> BCryptPasswordEncoder();<br>        String s = encoder.encode(<span class="hljs-string">&quot;abc&quot;</span>);<br>        System.out.println(s);<br>        String s1 = encoder.encode(<span class="hljs-string">&quot;abc&quot;</span>);<br>        System.out.println(s1);<br><br>        <span class="hljs-comment">// 进行判断</span><br>        <span class="hljs-keyword">boolean</span> b = encoder.matches(<span class="hljs-string">&quot;abc&quot;</span>, <span class="hljs-string">&quot;$2a$10$dyIf5fOjCRZs/pYXiBYy8uOiTa1z7I.mpqWlK5B/0icpAKijKCgxe&quot;</span>);<br>        System.out.println(b);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>加密后的格式一般为：</p>
<figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs elixir"><span class="hljs-variable">$2a</span><span class="hljs-variable">$10</span><span class="hljs-variable">$/</span>bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.<span class="hljs-number">6</span>oCa<br></code></pre></td></tr></table></figure>

<p>加密后字符串的长度为固定的60位。其中：</p>
<blockquote>
<p>$是分割符，无意义；</p>
<p>2a是bcrypt加密版本号；</p>
<p>10是cost的值；</p>
<p>而后的前22位是salt值；</p>
<p>再然后的字符串就是密码的密文了。</p>
</blockquote>
<p>实现步骤：</p>
<p>1：在spring-security.xml文件中指定密码加密对象</p>
<p>2：修改UserService实现类</p>
<p>第一步：在spring-security.xml文件中指定密码加密对象</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">    三：认证管理，定义登录账号名和密码，并授予访问的角色、权限</span><br><span class="hljs-comment">    authentication-manager：认证管理器，用于处理认证操作</span><br><span class="hljs-comment">--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-manager</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">        authentication-provider：认证提供者，执行具体的认证逻辑</span><br><span class="hljs-comment">    --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-provider</span> <span class="hljs-attr">user-service-ref</span>=<span class="hljs-string">&quot;userService&quot;</span>&gt;</span><br>        <span class="hljs-comment">&lt;!--指定密码加密策略--&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:password-encoder</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;passwordEncoder&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:password-encoder</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-provider</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-manager</span>&gt;</span><br><br><span class="hljs-comment">&lt;!--配置密码加密对象--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;passwordEncoder&quot;</span></span><br><span class="hljs-tag">      <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder&quot;</span> /&gt;</span><br></code></pre></td></tr></table></figure>

<p>第二步：修改UserService实现类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Component</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">UserDetailsService</span> </span>&#123;<br>    <span class="hljs-comment">//模拟数据库中的用户数据</span><br>   <span class="hljs-keyword">static</span> Map&lt;String,com.atguigu.pojo.User&gt; map =   <span class="hljs-keyword">new</span> HashMap&lt;String,com.atguigu.pojo.User&gt;();<br><br>   <span class="hljs-keyword">static</span> &#123;<br>       com.atguigu.pojo.User user1 =  <span class="hljs-keyword">new</span> com.atguigu.pojo.User();<br>       user1.setUsername(<span class="hljs-string">&quot;admin&quot;</span>);<br>       user1.setPassword(<span class="hljs-string">&quot;$2a$10$kRdUwbkOu8f.TRNHthPKquJE5yObiKov29Fo5qrnQK2j2qkjZLuEG&quot;</span>);<br>       user1.setTelephone(<span class="hljs-string">&quot;123&quot;</span>);<br><br>       com.atguigu.pojo.User user2 =  <span class="hljs-keyword">new</span> com.atguigu.pojo.User();<br>       user2.setUsername(<span class="hljs-string">&quot;zhangsan&quot;</span>);<br>       user2.setPassword(<span class="hljs-string">&quot;$2a$10$ay1JuL6FQHEVq7HorZGWZ.W0HgvXtwtfmzbe8R5H3on5nUtG/ZXDK&quot;</span>);<br>       user2.setTelephone(<span class="hljs-string">&quot;321&quot;</span>);<br><br>       map.put(user1.getUsername(),user1);<br>       map.put(user2.getUsername(),user2);<br>   &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 根据用户名加载用户信息</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> username</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     * <span class="hljs-doctag">@throws</span> UsernameNotFoundException</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> UserDetails <span class="hljs-title">loadUserByUsername</span><span class="hljs-params">(String username)</span> <span class="hljs-keyword">throws</span> UsernameNotFoundException </span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;username&quot;</span>+username);<br>        <span class="hljs-comment">//模拟根据用户名查询数据库</span><br>        com.atguigu.pojo.User userInDb = map.get(username);<br><br>        <span class="hljs-keyword">if</span> (userInDb==<span class="hljs-keyword">null</span>)&#123;<br>            <span class="hljs-comment">//根据用户名没有查询到用户，抛出异常，表示登录名输入有误</span><br>            <span class="hljs-keyword">return</span>  <span class="hljs-keyword">null</span>;<br>        &#125;<br>        <span class="hljs-comment">//模拟数据库中的密码，后期需要查询数据库</span><br><span class="hljs-comment">//        String passwordInDb =&quot;&#123;noop&#125;&quot; + userInDb.getPassword();</span><br>        String passwordInDb = userInDb.getPassword();<br>        <span class="hljs-comment">//授权，后期需要改为查询数据库动态获得用户拥有的权限和角色</span><br>        List&lt;GrantedAuthority&gt; lists = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;add&quot;</span>));<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;delete&quot;</span>));<br>        lists.add(<span class="hljs-keyword">new</span> SimpleGrantedAuthority(<span class="hljs-string">&quot;ROLE_ADMIN&quot;</span>));<br><br>        <span class="hljs-comment">//public User(String username, String password,</span><br>        <span class="hljs-comment">//Collection&lt;? extends GrantedAuthority &gt; authorities)</span><br>        <span class="hljs-comment">//返回User，参数一：存放登录名，</span><br>        <span class="hljs-comment">// 参数二：存放数据库查询的密码（数据库获取的密码，默认会和页面获取的密码进行比对，成功跳转到成功页面，失败回到登录页面，并抛出异常表示失败），存放当前用户具有的角色</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> User(username,passwordInDb,lists);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="配置多种校验规则（对页面）"><a href="#配置多种校验规则（对页面）" class="headerlink" title="配置多种校验规则（对页面）"></a>配置多种校验规则（对页面）</h3><p>为了测试方便，首先在项目的<code>webapp</code>文件夹下面创建 a.html、b.html、c.html、d.html几个页面</p>
<p>修改spring-security.xml文件：</p>
<p><strong>前提：&lt;security:http auto-config=“true” use-expressions=“true”&gt;</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">auto-config</span>=<span class="hljs-string">&quot;true&quot;</span> <span class="hljs-attr">use-expressions</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><br>   <span class="hljs-comment">&lt;!--&lt;security:intercept-url pattern=&quot;/**&quot; access=&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;&gt;&lt;/security:intercept-url&gt;--&gt;</span><br>    <span class="hljs-comment">&lt;!--只要认证通过就可以访问--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/index.html&quot;</span>  <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;isAuthenticated()&quot;</span> /&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/a.html&quot;</span>  <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;isAuthenticated()&quot;</span> /&gt;</span><br><br>    <span class="hljs-comment">&lt;!--拥有add权限就可以访问b.html页面--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/b.html&quot;</span>  <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasAuthority(&#x27;add&#x27;)&quot;</span> /&gt;</span><br><br>    <span class="hljs-comment">&lt;!--拥有ROLE_ADMIN角色就可以访问c.html页面，</span><br><span class="hljs-comment">        注意：此处虽然写的是ADMIN角色，框架会自动加上前缀ROLE_--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/c.html&quot;</span>  <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;</span> /&gt;</span><br><br>    <span class="hljs-comment">&lt;!--拥有ROLE_ADMIN角色就可以访问d.html页面--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/d.html&quot;</span>  <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ABC&#x27;)&quot;</span> /&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>测试：</p>
<p>登录后可以访问a.html,b.html,c.html，不能访问d.html</p>
<h3 id="注解方式权限控制（对类）"><a href="#注解方式权限控制（对类）" class="headerlink" title="注解方式权限控制（对类）"></a>注解方式权限控制（对类）</h3><p>Spring Security除了可以在配置文件中配置权限校验规则，还可以使用注解方式控制类中方法的调用。例如Controller中的某个方法要求必须具有某个权限才可以访问，此时就可以使用Spring Security框架提供的注解方式进行控制。</p>
<p>【路径】</p>
<p>1：在spring-security.xml文件中配置组件扫描和mvc的注解驱动，用于扫描Controller</p>
<p>2：在spring-security.xml文件中开启权限注解支持</p>
<p>3：创建Controller类并在Controller的方法上加入注解（@PreAuthorize）进行权限控制</p>
<p>实现步骤：</p>
<p>第一步：在spring-security.xml文件中配置组件扫描，用于扫描Controller</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">context:component-scan</span> <span class="hljs-attr">base-package</span>=<span class="hljs-string">&quot;com&quot;</span>/&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>第二步：在spring-security.xml文件中开启权限注解支持</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--开启注解方式权限控制--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:global-method-security</span> <span class="hljs-attr">pre-post-annotations</span>=<span class="hljs-string">&quot;enabled&quot;</span> /&gt;</span><br></code></pre></td></tr></table></figure>

<p>第三步：创建Controller类并在Controller的方法上加入注解（@PreAuthorize）进行权限控制</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@RestController</span><br><span class="hljs-meta">@RequestMapping(&quot;/hello&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HelloController</span> </span>&#123;<br><br>    <span class="hljs-meta">@RequestMapping(&quot;/add&quot;)</span><br>    <span class="hljs-meta">@PreAuthorize(&quot;hasAuthority(&#x27;add&#x27;)&quot;)</span><span class="hljs-comment">//表示用户必须拥有add权限才能调用当前方法</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">add</span><span class="hljs-params">()</span></span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;add...&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;success&quot;</span>;<br>    &#125;<br><br>    <span class="hljs-meta">@RequestMapping(&quot;/update&quot;)</span><br>    <span class="hljs-meta">@PreAuthorize(&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;)</span><span class="hljs-comment">//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">update</span><span class="hljs-params">()</span></span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;update...&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;success&quot;</span>;<br>    &#125;<br><br>    <span class="hljs-meta">@RequestMapping(&quot;/delete&quot;)</span><br>    <span class="hljs-meta">@PreAuthorize(&quot;hasRole(&#x27;ABC&#x27;)&quot;)</span><span class="hljs-comment">//表示用户必须拥有ABC角色才能调用当前方法</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">delete</span><span class="hljs-params">()</span></span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;delete...&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;success&quot;</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>测试delete方法不能访问</p>
<p><img src="http://www.slx.blue/2022/01/08/SpringSecurity/s014.png" srcset="/img/loading.gif" lazyload alt="s014"></p>
<h3 id="退出登录"><a href="#退出登录" class="headerlink" title="退出登录"></a><strong>退出登录</strong></h3><p>用户完成登录后Spring Security框架会记录当前用户认证状态为已认证状态，即表示用户登录成功了。那用户如何退出登录呢？我们可以在spring-security.xml文件中进行如下配置：</p>
<ol>
<li>index.html定义退出登录链接</li>
<li>在spring-security.xml定义</li>
</ol>
<p>第一步：index.html定义退出登录链接</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Title<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    登录成功！<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;/logout.do&quot;</span>&gt;</span>退出登录<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>第二步：在spring-security.xml定义：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">  logout：退出登录</span><br><span class="hljs-comment">  logout-url：退出登录操作对应的请求路径</span><br><span class="hljs-comment">  logout-success-url：退出登录后的跳转页面</span><br><span class="hljs-comment">  invalidate-session=&quot;true&quot; 默认为true,用户在退出后Http session失效</span><br><span class="hljs-comment">--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:logout</span> <span class="hljs-attr">logout-url</span>=<span class="hljs-string">&quot;/logout.do&quot;</span></span><br><span class="hljs-tag">                 <span class="hljs-attr">logout-success-url</span>=<span class="hljs-string">&quot;/login.html&quot;</span> <span class="hljs-attr">invalidate-session</span>=<span class="hljs-string">&quot;true&quot;</span>/&gt;</span><br></code></pre></td></tr></table></figure>

<p> 通过上面的配置可以发现，如果用户要退出登录，只需要请求/logout.do这个URL地址就可以，同时会将当前session失效，最后页面会跳转到login.html页面。</p>
<h3 id="【小结】-2"><a href="#【小结】-2" class="headerlink" title="【小结】"></a><a href="#%E5%B0%8F%E7%BB%93-">【小结】</a></h3><p>1：配置可匿名访问的资源(不需要登录,权限 角色 就可以访问)</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/js/**&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/css/**&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:http</span> <span class="hljs-attr">security</span>=<span class="hljs-string">&quot;none&quot;</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/login.html&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:http</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>2：使用指定的登录页面（login.html)</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:form-login</span> <span class="hljs-attr">login-page</span>=<span class="hljs-string">&quot;/login.html&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">username-parameter</span>=<span class="hljs-string">&quot;username&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">password-parameter</span>=<span class="hljs-string">&quot;password&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">login-processing-url</span>=<span class="hljs-string">&quot;/login.do&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">default-target-url</span>=<span class="hljs-string">&quot;/index.html&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">authentication-failure-url</span>=<span class="hljs-string">&quot;/login.html&quot;</span></span><br><span class="hljs-tag">                     <span class="hljs-attr">always-use-default-target</span>=<span class="hljs-string">&quot;true&quot;</span>/&gt;</span><br></code></pre></td></tr></table></figure>

<p>3：从数据库查询用户信息</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-manager</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">security:authentication-provider</span> <span class="hljs-attr">user-service-ref</span>=<span class="hljs-string">&quot;userService&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">security:password-encoder</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;bCryptPasswordEncoder&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:password-encoder</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-provider</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">security:authentication-manager</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>4：对密码进行加密</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;bCryptPasswordEncoder&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>5：配置多种校验规则（对访问的页面做权限控制）</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/index.html&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;isAuthenticated()&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/a.html&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;isAuthenticated()&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/b.html&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasAuthority(&#x27;add&#x27;)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/c.html&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ROLE_ADMIN&#x27;)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">security:intercept-url</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">&quot;/d.html&quot;</span> <span class="hljs-attr">access</span>=<span class="hljs-string">&quot;hasRole(&#x27;ABC&#x27;)&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:intercept-url</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>6：注解方式权限控制（对访问的Controller类做权限控制）</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:global-method-security</span> <span class="hljs-attr">pre-post-annotations</span>=<span class="hljs-string">&quot;enabled&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">security:global-method-security</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>7：退出登录</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">security:logout</span> <span class="hljs-attr">logout-url</span>=<span class="hljs-string">&quot;/logout.do&quot;</span> <span class="hljs-attr">logout-success-url</span>=<span class="hljs-string">&quot;/login.html&quot;</span> <span class="hljs-attr">inv</span></span><br></code></pre></td></tr></table></figure>
            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/SpringSecurity/">SpringSecurity</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/SpringSecurity/">SpringSecurity</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客目前大部分文章都是参考尚硅谷或者马士兵教育的学习资料！<a href="http://www.atguigu.com/" rel="nofollow noopener"官网地址！</a> 
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/01/11/ElasticSearch/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">ElasticSearch-高级客户端</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/12/28/Quartz/">
                        <span class="hidden-mobile">定时任务组件Quartz</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
              <!-- Comments -->
              <article class="comments" id="comments" lazyload>
                
                  
                
                

              </article>
            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">

  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
	<!--《添加网站运行时间 -->
<br/>

<span id="timeDate">载入天数...</span><span id="times">载入时分秒...</span>
<script>
var now = new Date(); 

function createtime() {
    //此处修改你的建站时间或者网站上线时间
    var grt = new Date('11/02/2021 21:39:00');
    now.setTime(now.getTime() + 250);
    days = (now - grt) / 1000 / 60 / 60 / 24;

    dnum = Math.floor(days);
    hours = (now - grt) / 1000 / 60 / 60 - (24 * dnum);
    hnum = Math.floor(hours);
    if (String(hnum).length == 1) {
        hnum = "0" + hnum;
    }
    minutes = (now - grt) / 1000 / 60 - (24 * 60 * dnum) - (60 * hnum);
    mnum = Math.floor(minutes);
    if (String(mnum).length == 1) {
        mnum = "0" + mnum;
    }
    seconds = (now - grt) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum);
    snum = Math.round(seconds);
    if (String(snum).length == 1) {
        snum = "0" + snum;
    }
    document.getElementById("timeDate").innerHTML = " 本站已各种夹缝中安全运行 " + dnum + " 天 ";
    document.getElementById("times").innerHTML = hnum + " 小时 " + mnum + " 分 " + snum + " 秒";
}
setInterval("createtime()", 250);
</script>

<!-- 添加网站运行时间》-->
  </div>
  
  <div class="statistics">
    
    

    
      
        <!-- 不蒜子统计PV -->
        <span id="busuanzi_container_site_pv" style="display: none">
            总访问量 
            <span id="busuanzi_value_site_pv"></span>
             次
          </span>
      
      
        <!-- 不蒜子统计UV -->
        <span id="busuanzi_container_site_uv" style="display: none">
            总访客数 
            <span id="busuanzi_value_site_uv"></span>
             人
          </span>
      
    
  </div>


  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/js/local-search.js" ></script>



  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>


</body>
</html>
